open Ast
open Gen
open Arbreintermediaire
open Arbre_selection_instruction

let rec afficher_label(lb) =
    Gen.label_name(lb)

and afficher_registre(registre) =
  match registre with
    | Registre r ->
      "$"^(string_of_int r)
    | RegNom nom ->
      "$"^nom

and afficher_registre_liste(registres) =
  match registres with
    | [] -> ""
    | registre::[] -> afficher_registre(registre)
    | registre::reste -> afficher_registre(registre)^afficher_registre_liste(reste)


and afficher_frame(frame) =
  (frame.name^"={"^
    "entry: "^afficher_label(frame.lentry)^
    " , return: "^afficher_label(frame.lreturn)^
    " , args: ["^afficher_registre_liste(frame.args)^"]"^
    " , result: "^afficher_registre(frame.result)^
    " , stack: "^(string_of_int frame.stack)^
  "}")


let rec afficher_operation (op) = 
  match op with 
  | ADD -> "add"
  | MIN -> "min"
  | MUL -> "mul"
  | DIV -> "div"
  | AND -> "and"
  | OR  -> "or"
  | NOT -> "nor"

let rec afficher_comparaison(c) = 
  match c with
  | BLT -> "blt"
  | BGT -> "bgt"
  | BLE -> "ble"
  | BGE -> "bge"
  | BEG -> "beg"
  | BNE -> "bne"

let rec afficher_instructions(lst) = 
  match lst with
  | [] -> ""
  | l::[] -> afficher_instruction (l)
  | l::r -> afficher_instruction (l)^"\n"^afficher_instructions(r)

and afficher_instruction(inst) =
  match inst with
  | LABEL (l) ->
      afficher_label(l)^":"
  | LIST (lst) ->
      afficher_instructions(lst)
  | LI (r,v) ->
      "\t"^
      "li "^
      afficher_registre(r)^","^
      string_of_int(v)
  | MOVE (r1,r2) ->
      "\t"^
      "move "^
      afficher_registre(r1)^","^
      afficher_registre(r2)
	| NOP ->
      "\t"^
      "nop"
  | OPERATION (op,out,r1,r2) ->
      "\t"^
      afficher_operation(op)^" "^
      afficher_registre(out)^","^
      afficher_registre(r1)^","^
      afficher_registre(r2)
  | BRANCH (comp, r1, r2, l) -> 
      "\t"^
      afficher_comparaison(comp)^" "^
      afficher_registre(r1)^","^
      afficher_registre(r2)^","^
      afficher_label(l)
  | J (l) -> 
      "\t"^
      "j "^afficher_label(l)
  | JAL (l) -> 
      "\t"^
      "jal "^afficher_label(l)
  | JR (r) ->
      "\t"^
      "jr "^afficher_registre(r)
  | PRINT ->
      "\t"^"move $v0,1\n"^
      "\t"^"syscall"


let rec afficher_sFrame(fr) =
  match fr with
  | SFrame(f,i) ->
    "\n"^"\n"^
    afficher_frame(f)^"\n"^"\n"^
    afficher_instruction(i)

let rec afficher_sFrames(lst) =
  match lst with
  | [] -> ""
  | f::r -> afficher_sFrame(f)^afficher_sFrames(r)


let rec afficher_text(t) = 
  ".text\n\n"^
  "j MAIN_1\n\n"^
	afficher_sFrames(t.sframes)^"\n\n\n\n"^
  afficher_instruction(t.stext)


let sel_afficher(prog) = 
  let oo = open_out "selection.txt" in
    let string_prog = afficher_text(prog) in
    begin
      output_string oo string_prog;
      close_out oo
    end